#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "uart.h"

#define TAG "uart"
#define USER_UART_NUM UART_NUM_2

SemaphoreHandle_t g_uart_buffer_sem = NULL;
char uart_buffer[UART_BUFFER_SIZE];
static QueueHandle_t uart_queue;

void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    g_uart_buffer_sem = xSemaphoreCreateBinary();   // 初始化信号量
    xSemaphoreGive(g_uart_buffer_sem);              // 初始释放信号量
    
    uart_config_t uart_cfg={
        .baud_rate=9600,                            //波特率9600
        .data_bits=UART_DATA_8_BITS,                //8位数据位
        .flow_ctrl=UART_HW_FLOWCTRL_DISABLE,        //无硬件流控制
        .parity=UART_PARITY_DISABLE,                //无校验位
        .stop_bits=UART_STOP_BITS_1                 //1位停止位
    };
    uart_driver_install(USER_UART_NUM, 1024, 1024, 20, &uart_queue, 0);                             //安装串口驱动，函数带有接收缓冲区大小、发送缓冲区大小、事件队列大小。
    uart_param_config(USER_UART_NUM, &uart_cfg);
    uart_set_pin(USER_UART_NUM, GPIO_NUM_17,GPIO_NUM_16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);   //设置引脚,tx为17,rx为16
    
    while (1)
    {
        // 获取信号量
        if (xSemaphoreTake(g_uart_buffer_sem, pdMS_TO_TICKS(3000)) != pdPASS){
            continue;
        }
        // 等待UART事件的发生。这里使用portMAX_DELAY表示无限等待，直到有事件发生
        if (xQueueReceive(uart_queue, (void *)&event, (TickType_t)portMAX_DELAY)) 
        {
            ESP_LOGI(TAG, "uart[%d] event:", USER_UART_NUM); // 当UART事件发生时，打印事件类型
            switch (event.type){ // 根据事件类型进行不同的处理
            case UART_DATA:{                                                            // 当事件类型为UART_DATA时，表示有数据被接收
                ESP_LOGI(TAG, "[UART DATA]: %d", event.size);                           // 打印接收到的数据大小
                memset(uart_buffer, 0, event.size);                                     // 按需清零uart_buffer
                uart_read_bytes(USER_UART_NUM, uart_buffer, event.size, portMAX_DELAY); // 从UART读取接收到的数据到uart_buffer中，读取的字节数为event.size
                ESP_LOGI(TAG, "[DATA EVT]: %s", uart_buffer);                           // 打印接收到的数据
                break;
            }
            case UART_FIFO_OVF:{                        // 当硬件FIFO溢出时触发的事件
                ESP_LOGI(TAG, "hw fifo overflow");      // 打印硬件FIFO溢出信息
                uart_flush_input(USER_UART_NUM);        // 清空UART输入缓冲区
                xQueueReset(uart_queue);                // 重置UART事件队列
                break;
            }
            case UART_BUFFER_FULL:{                     // 当UART环形缓冲区满时触发的事件
                ESP_LOGI(TAG, "ring buffer full");      // 打印环形缓冲区已满的信息
                uart_flush_input(USER_UART_NUM);        // 清空UART输入缓冲区，以便读取更多数据
                xQueueReset(uart_queue);                // 重置UART事件队列
                break;
            }
            case UART_BREAK:{                           // 当检测到UART接收中断时触发的事件
                ESP_LOGI(TAG, "uart rx break");
                break;
            }
            case UART_PARITY_ERR:{                      // 当检测到UART奇偶校验错误时触发的事件
                ESP_LOGI(TAG, "uart parity error");
                break;
            }
            case UART_FRAME_ERR:{                       // 当检测到UART帧错误时触发的事件
                ESP_LOGI(TAG, "uart frame error");
                break;
            }
            default:
                ESP_LOGI(TAG, "uart event type: %d", event.type);
                break;
            }
        }
        xSemaphoreGive(g_uart_buffer_sem);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    vTaskDelete(NULL);
}


